package tenumn.energytech.registrys.machine;

import io.github.uicdb.liba.api.util.ITickable;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import tenumn.energytech.registrys.item.ItemMachinePlugin;

import javax.annotation.Nonnull;
import java.util.HashMap;

public abstract class MachineBlockEntity extends BlockEntity implements ITickable {
    private final HashMap<Upgradeable, ItemStack> upgradeMap=new HashMap<>();
    public MachineBlockEntity(BlockEntityType<?> pType, BlockPos pWorldPosition, BlockState pBlockState) {
        super(pType, pWorldPosition, pBlockState);
    }

    public enum Upgradeable{
        ENERGY_STORAGE, OVERCLOCKING, EFFICIENCY, ITEM_OUTPUT, EMPTY
        }
    protected void onUpgradeChanged(Upgradeable type){}
    protected boolean canInsertUpgrade(Upgradeable type,@Nonnull ItemStack newOne){
        if(!(newOne.getItem() instanceof ItemMachinePlugin))return false;
        ItemStack itemStack=upgradeMap.get(type);
        return itemStack == null || (newOne.sameItem(itemStack) && itemStack.getCount() < itemStack.getMaxStackSize());
    }
    public ItemStack insertUpgrade(Upgradeable type,ItemStack newUpgradeStack){
        if (canInsertUpgrade(type, newUpgradeStack)){
            ItemStack itemStack=upgradeMap.get(type);
            if(itemStack==null) {
                upgradeMap.put(type, newUpgradeStack);
                onUpgradeChanged(type);
            }
            else {
                int add=Math.min(itemStack.getMaxStackSize()-itemStack.getCount(),newUpgradeStack.getCount());
                var result=itemStack.copy();
                itemStack.grow(add);
                result.shrink(add);
                onUpgradeChanged(type);
                return result;
            }
        }
        return newUpgradeStack;
    }
    public ItemStack removeUpgrade(Upgradeable type,int count){
        ItemStack itemStack=upgradeMap.get(type);
        if(itemStack==null)return ItemStack.EMPTY;
        else {
            int removed=Math.min(count,itemStack.getCount());
            ItemStack result=itemStack.split(removed);
            onUpgradeChanged(type);
            return result;
        }
    }

    @Override
    protected void saveAdditional(@Nonnull CompoundTag pTag) {
        super.saveAdditional(pTag);
        CompoundTag upgrade=new CompoundTag();
        upgradeMap.forEach(((upgradeable, itemStack) -> upgrade.put(upgradeable.name(),itemStack.save(new CompoundTag()))));
        pTag.put("Upgrade",upgrade);
    }

    @Override
    public void load(@Nonnull CompoundTag pTag) {
        super.load(pTag);
        CompoundTag upgrade=pTag.getCompound("Upgrade");
        upgrade.getAllKeys().forEach(key->{
            upgradeMap.put(Upgradeable.valueOf(key),ItemStack.of(upgrade.getCompound(key)));
        });
    }
}
